package com.kayb.patterns.behavioral;

/**
 * 策略模式，定义一系列算法，并将每个算法封装起来，使得他们之间可以单独互相替换，且算法的变化不会影响到使用算法的客户
 * 实现：定义一个接口，多个类实现该接口，必要时可以使用抽象类定义一些公共方法
 * 场景：有多个不同实现
 * vs 工厂模式：策略模式属于行为模式，根据创建好的对象执行不同的行为
 * vs 模板方法：策略模式是一个完整的算法，算法是可以被整体替换的。模板方法则侧重的是算法的整体流程固定不变，子算法可以自由实现。
 * @author huangkaibin
 * @date 2018-08-28
 **/
public class Strategy {

    interface DragonSlayingStrategy {
        void execute();
    }

    static class MeleeStrategy implements DragonSlayingStrategy {
        @Override
        public void execute() {
            System.out.println("MeleeStrategy");
        }
    }

    static class ProjectileStrategy implements DragonSlayingStrategy {
        @Override
        public void execute() {
            System.out.println("ProjectileStrategy");
        }
    }

    static class SpellStrategy implements DragonSlayingStrategy {
        @Override
        public void execute() {
            System.out.println("SpellStrategy");
        }
    }

    static class DragonSlayer {

        private DragonSlayingStrategy strategy;

        public DragonSlayer(DragonSlayingStrategy strategy) {
            this.strategy = strategy;
        }

        public void changeStrategy(DragonSlayingStrategy strategy) {
            this.strategy = strategy;
        }

        public void goToBattle() {
            strategy.execute();
        }
    }

    public static void main(String[] args) {
        DragonSlayer dragonSlayer = new DragonSlayer(new MeleeStrategy());
        dragonSlayer.goToBattle();
        dragonSlayer.changeStrategy(new ProjectileStrategy());
        dragonSlayer.goToBattle();
        dragonSlayer.changeStrategy(new SpellStrategy());
        dragonSlayer.goToBattle();
    }

}
